﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Net;

namespace HexTileBoard
{
    public static class BoardFunctions
    {
        public static void EndTurn(ref Board _board, NetworkSession networkSession)
        {
            // Send network updates
            //if ((networkSession != null) && (networkSession.LocalGamers.Count > 0))
            //{
            //    PacketWriter packetWriter = new PacketWriter();

            //    // write the identification value
            //    packetWriter.Write((Int32)PacketTypes.PlayerAction);

            //    // Send the active
            //    packetWriter.Write((Int32)_board.currentPlayer.Side);

            //    // Send our "End Turn" action
            //    packetWriter.Write((Int32)PlayerActions.EndTurn);

            //    // Send empty values for source/target indices
            //    packetWriter.Write((Int32)(-1));
            //    packetWriter.Write((Int32)(-1));

            //    networkSession.LocalGamers[0].SendData(packetWriter, SendDataOptions.ReliableInOrder);
            //}

            _board.turnCount++;

            // Stop trading
            _board.IsTrading = false;
            _board.TradingResource = (HexTileResource)BoardConstructor.random.Next(1, 6);

            // If wood or iron, randomize up to twice more, just because we need them least
            int i = 0;
            while ((_board.TradingResource == HexTileResource.Wood || _board.TradingResource == HexTileResource.Iron) && i < 2)
            {
                _board.TradingResource = (HexTileResource)BoardConstructor.random.Next(1, 6);
                i++;
            }

            _board.clayTrade = BoardConstructor.random.Next(2, 5);
            _board.stoneTrade = BoardConstructor.random.Next(2, 5);
            _board.wheatTrade = BoardConstructor.random.Next(2, 5);
            _board.woodTrade = BoardConstructor.random.Next(3, 5);

            // Clear selected tile
            _board.currentPlayer.SelectedTile = null;

            // Track previous player for camera purposes
            Player previousPlayer = _board.currentPlayer;

            // Accumulate resources for the player ending turn
            foreach (KeyValuePair<PlayerColor, Player> p in _board.Players)
            {
                if (p.Value.Side == _board.currentPlayer.Side)
                {
                    // Add dynamic text showing new resources
                    if (p.Value.OwnedResources[HexTileResource.Clay] > 0)
                        _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("+" + p.Value.OwnedResources[HexTileResource.Clay].ToString(), new Vector2(_board.widthFraction + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    if (p.Value.OwnedResources[HexTileResource.Iron] > 0)
                        _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("+" + p.Value.OwnedResources[HexTileResource.Iron].ToString(), new Vector2(_board.widthFraction * 2 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    if (p.Value.OwnedResources[HexTileResource.Stone] > 0)
                        _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("+" + p.Value.OwnedResources[HexTileResource.Stone].ToString(), new Vector2(_board.widthFraction * 3 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    if (p.Value.OwnedResources[HexTileResource.Wheat] > 0)
                        _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("+" + p.Value.OwnedResources[HexTileResource.Wheat].ToString(), new Vector2(_board.widthFraction * 4 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    if (p.Value.OwnedResources[HexTileResource.Wood] > 0)
                        _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("+" + p.Value.OwnedResources[HexTileResource.Wood].ToString(), new Vector2(_board.widthFraction * 5 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));

                    p.Value.CurrentResources[HexTileResource.Clay] += p.Value.OwnedResources[HexTileResource.Clay];
                    p.Value.CurrentResources[HexTileResource.Iron] += p.Value.OwnedResources[HexTileResource.Iron];
                    p.Value.CurrentResources[HexTileResource.Stone] += p.Value.OwnedResources[HexTileResource.Stone];
                    p.Value.CurrentResources[HexTileResource.Wheat] += p.Value.OwnedResources[HexTileResource.Wheat];
                    p.Value.CurrentResources[HexTileResource.Wood] += p.Value.OwnedResources[HexTileResource.Wood];

                    p.Value.CurrentResources[HexTileResource.Clay] = (int)MathHelper.Clamp(p.Value.CurrentResources[HexTileResource.Clay], 0, 99);
                    p.Value.CurrentResources[HexTileResource.Iron] = (int)MathHelper.Clamp(p.Value.CurrentResources[HexTileResource.Iron], 0, 99);
                    p.Value.CurrentResources[HexTileResource.Stone] = (int)MathHelper.Clamp(p.Value.CurrentResources[HexTileResource.Stone], 0, 99);
                    p.Value.CurrentResources[HexTileResource.Wheat] = (int)MathHelper.Clamp(p.Value.CurrentResources[HexTileResource.Wheat], 0, 99);
                    p.Value.CurrentResources[HexTileResource.Wood] = (int)MathHelper.Clamp(p.Value.CurrentResources[HexTileResource.Wood], 0, 99);

                    // Exit after accumulating for current player
                    break;
                }
            }

            // Check game winning
            foreach (KeyValuePair<PlayerColor, Player> p in _board.Players)
            {
                // Win by resource
                if (p.Value.CurrentResources[HexTileResource.Clay] == 99 && p.Value.CurrentResources[HexTileResource.Iron] == 99 && p.Value.CurrentResources[HexTileResource.Stone] == 99 && p.Value.CurrentResources[HexTileResource.Wheat] == 99 && p.Value.CurrentResources[HexTileResource.Wood] == 99)
                {
                    _board.gameOver = true;
                    _board.winningPlayer = p.Value.Side;
                    _board.winningType = "Won by maximum resources!";
                    break;
                }

                // Win by percentage of influence
                if ((p.Value.tilesOwned.Count / (float)_board.Tiles.Length) > BoardVariables.PercentOfBoard)
                {
                    _board.gameOver = true;
                    _board.winningPlayer = p.Value.Side;
                    _board.winningType = "Occupied the board!";
                }
            }

            // Change current player
            if (!_board.gameOver)
            {
                // Change to next in order. Always added in order, so can check if color is present in order.
                switch (_board.currentPlayer.Side)
                {
                    case PlayerColor.Blue:
                        if (_board.Players.ContainsKey(PlayerColor.Red))
                            _board.currentPlayer = _board.Players[PlayerColor.Red];
                        else if (_board.Players.ContainsKey(PlayerColor.Green))
                            _board.currentPlayer = _board.Players[PlayerColor.Green];
                        else if (_board.Players.ContainsKey(PlayerColor.Yellow))
                            _board.currentPlayer = _board.Players[PlayerColor.Yellow];
                        break;
                    case PlayerColor.Red:
                        if (_board.Players.ContainsKey(PlayerColor.Green))
                            _board.currentPlayer = _board.Players[PlayerColor.Green];
                        else if (_board.Players.ContainsKey(PlayerColor.Yellow))
                            _board.currentPlayer = _board.Players[PlayerColor.Yellow];
                        else if (_board.Players.ContainsKey(PlayerColor.Blue))
                            _board.currentPlayer = _board.Players[PlayerColor.Blue];
                        break;
                    case PlayerColor.Green:
                        if (_board.Players.ContainsKey(PlayerColor.Yellow))
                            _board.currentPlayer = _board.Players[PlayerColor.Yellow];
                        else if (_board.Players.ContainsKey(PlayerColor.Blue))
                            _board.currentPlayer = _board.Players[PlayerColor.Blue];
                        else if (_board.Players.ContainsKey(PlayerColor.Red))
                            _board.currentPlayer = _board.Players[PlayerColor.Red];
                        break;
                    case PlayerColor.Yellow:
                        if (_board.Players.ContainsKey(PlayerColor.Blue))
                            _board.currentPlayer = _board.Players[PlayerColor.Blue];
                        else if (_board.Players.ContainsKey(PlayerColor.Red))
                            _board.currentPlayer = _board.Players[PlayerColor.Red];
                        else if (_board.Players.ContainsKey(PlayerColor.Green))
                            _board.currentPlayer = _board.Players[PlayerColor.Green];
                        break;
                }

                // Track the camera positions we want in order to transition back
                _board.currentPlayer.Camera.DesiredPosition = _board.currentPlayer.Camera.CameraPosition;
                _board.currentPlayer.Camera.DesiredTarget = _board.currentPlayer.Camera.CameraTarget;
                _board.currentPlayer.Camera.CameraPosition = previousPlayer.Camera.CameraPosition;
                _board.currentPlayer.Camera.CameraTarget = previousPlayer.Camera.CameraTarget;

                // Change cursor input
                _board.cursor.currentPlayerIndex = _board.currentPlayer.playerIndex;
                _board.cursor.PlayerIsAI = _board.currentPlayer.IsAI;

                // show what is for trade
                if (!_board.currentPlayer.canBuildFirst)
                {
                    _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine(_board.TradingResource.ToString() + " is offered for trade.", new Vector2((_board.screenWidth / 2) - (_board.spriteFontSmall.MeasureString(_board.TradingResource.ToString() + " is offered for trade.").X / 2), _board.heightPadding * 6), _board.spriteFontSmall, Color.White, 0, 2000, -Vector2.UnitY, 0.05f, 1.0f, -0.0015f, 1000, 0.0f, 2000, DynamicTextLine.OriginType.TopLeft, Color.Black));
                }
            }
            else
            {
                _board.endSound.Play();
            }

            // Give starting player a minimum of resources if knocked out
            if (!_board.currentPlayer.canBuildFirst && _board.currentPlayer.tilesOwned.Count == 0 && _board.turnCount > _board.Players.Count)
            {
                _board.currentPlayer.CurrentResources[HexTileResource.Clay] = 5;
                _board.currentPlayer.CurrentResources[HexTileResource.Stone] = 5;
                _board.currentPlayer.CurrentResources[HexTileResource.Wood] = 5;
                _board.currentPlayer.CurrentResources[HexTileResource.Wheat] = 2;
                _board.currentPlayer.CurrentResources[HexTileResource.Iron] = 1;

                System.Threading.Thread.Sleep(500);
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine(_board.currentPlayer.Side.ToString() + " given a minimum of resources.", new Vector2((_board.screenWidth / 2) - (_board.spriteFontSmall.MeasureString(_board.currentPlayer.Side.ToString() + " given a minimum of resources.").X / 2), _board.heightPadding * 6), _board.spriteFontSmall, Color.White, 0, 2000, -Vector2.UnitY, 0.05f, 1.0f, -0.0015f, 1000, 0.0f, 2000, DynamicTextLine.OriginType.TopLeft, Color.Black));
            }

            //System.Threading.Thread.Sleep(500);
        }

        public static void UpdateInfluence(ref Board _board)
        {
            BoardVariables.UpdatingInfluence = true;

            // Track indexes already updated
            List<int> indexesUpdated = new List<int>();

            // Reset player counts so that we can sum later
            foreach (KeyValuePair<PlayerColor, Player> p in _board.Players)
            {
                p.Value.tilesOwned.Clear();
                p.Value.OwnedResources[HexTileResource.None] = 0;
                p.Value.OwnedResources[HexTileResource.Clay] = 0;
                p.Value.OwnedResources[HexTileResource.Iron] = 0;
                p.Value.OwnedResources[HexTileResource.Stone] = 0;
                p.Value.OwnedResources[HexTileResource.Wheat] = 0;
                p.Value.OwnedResources[HexTileResource.Wood] = 0;
            }

            // Total up the influence for each tower (does not include scaffolds [do not stack] or bridges [no influence])
            // Each tile has counter for each color, and final color/value
            // i.e. redInfluence = 3, blueInfluence = 2, influence = red, value = 1
            for (int i = 0; i < _board.Tiles.Length; i++)
            {
                _board.Tiles[i].previousValue = _board.Tiles[i].value;

                if (_board.Tiles[i].ManMadeModifier != HexTileManMadeModifier.None)
                {
                    // -----------------------------------
                    // Level 1
                    // -----------------------------------
                    if (_board.Tiles[i].ManMadeModifier == HexTileManMadeModifier.InfluenceTower1 ||
                        _board.Tiles[i].ManMadeModifier == HexTileManMadeModifier.InfluenceTower2 ||
                        _board.Tiles[i].ManMadeModifier == HexTileManMadeModifier.InfluenceTower3)
                    {
                        // Update the value for closest _board.Tiles
                        _board.Tiles[i].color[_board.Tiles[i].buildingOwner] += (int)_board.Tiles[i].ManMadeModifier;
                        indexesUpdated.Add(_board.Tiles[i].IndexInBoard);
                        for (int j = 0; j < 6; j++)
                        {
                            if (_board.Tiles[i].Neighbors[j] != null && _board.Tiles[i].Neighbors[j].TileBase == HexTileBase.Grass)
                            {
                                _board.Tiles[i].Neighbors[j].color[_board.Tiles[i].buildingOwner] += (int)_board.Tiles[i].ManMadeModifier;
                                indexesUpdated.Add(_board.Tiles[i].Neighbors[j].IndexInBoard);
                            }
                        }

                        // -----------------------------------
                        // Level 2
                        // -----------------------------------
                        if (_board.Tiles[i].ManMadeModifier == HexTileManMadeModifier.InfluenceTower2 ||
                            _board.Tiles[i].ManMadeModifier == HexTileManMadeModifier.InfluenceTower3)
                        {
                            for (int j = 0; j < 6; j++)
                            {
                                if (_board.Tiles[i].Neighbors[j] != null && (_board.Tiles[i].Neighbors[j].TileBase == HexTileBase.Grass || _board.Tiles[i].Neighbors[j].ManMadeModifier == HexTileManMadeModifier.Bridge))
                                {
                                    // Update second row
                                    for (int k = 0; k < 6; k++)
                                    {
                                        if (_board.Tiles[i].Neighbors[j].Neighbors[k] != null && _board.Tiles[i].Neighbors[j].Neighbors[k].TileBase == HexTileBase.Grass
                                            && !indexesUpdated.Contains(_board.Tiles[i].Neighbors[j].Neighbors[k].IndexInBoard))
                                        {
                                            // Mountains reduce influence
                                            if (_board.Tiles[i].Neighbors[j].Neighbors[k].NaturalModifier == HexTileNaturalModifier.Mountain1 || _board.Tiles[i].Neighbors[j].Neighbors[k].NaturalModifier == HexTileNaturalModifier.Mountain2 || _board.Tiles[i].Neighbors[j].Neighbors[k].NaturalModifier == HexTileNaturalModifier.Mountain3)
                                            {
                                                _board.Tiles[i].Neighbors[j].Neighbors[k].color[_board.Tiles[i].buildingOwner]++;
                                            }
                                            else
                                            {
                                                _board.Tiles[i].Neighbors[j].Neighbors[k].color[_board.Tiles[i].buildingOwner] += (int)_board.Tiles[i].ManMadeModifier - 1;
                                            }
                                            indexesUpdated.Add(_board.Tiles[i].Neighbors[j].Neighbors[k].IndexInBoard);
                                        }
                                    }
                                }
                            }
                        }

                        // -----------------------------------
                        // Level 3
                        // -----------------------------------
                        if (_board.Tiles[i].ManMadeModifier == HexTileManMadeModifier.InfluenceTower3)
                        {
                            for (int j = 0; j < 6; j++)
                            {
                                if (_board.Tiles[i].Neighbors[j] != null && (_board.Tiles[i].Neighbors[j].TileBase == HexTileBase.Grass || _board.Tiles[i].Neighbors[j].ManMadeModifier == HexTileManMadeModifier.Bridge))
                                {
                                    // Update second row
                                    for (int k = 0; k < 6; k++)
                                    {
                                        if (_board.Tiles[i].Neighbors[j].Neighbors[k] != null && (_board.Tiles[i].Neighbors[j].Neighbors[k].TileBase == HexTileBase.Grass || _board.Tiles[i].Neighbors[j].Neighbors[k].ManMadeModifier == HexTileManMadeModifier.Bridge))
                                        {
                                            // update third row
                                            for (int l = 0; l < 6; l++)
                                            {
                                                if (_board.Tiles[i].Neighbors[j].Neighbors[k].Neighbors[l] != null && _board.Tiles[i].Neighbors[j].Neighbors[k].Neighbors[l].TileBase == HexTileBase.Grass
                                                    && !indexesUpdated.Contains(_board.Tiles[i].Neighbors[j].Neighbors[k].Neighbors[l].IndexInBoard))
                                                {
                                                    _board.Tiles[i].Neighbors[j].Neighbors[k].Neighbors[l].color[_board.Tiles[i].buildingOwner]++;
                                                    indexesUpdated.Add(_board.Tiles[i].Neighbors[j].Neighbors[k].Neighbors[l].IndexInBoard);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }

                        //Clear existing indexes
                        indexesUpdated.Clear();
                    }
                    else if (_board.Tiles[i].ManMadeModifier == HexTileManMadeModifier.DefensiveTower)
                    {
                        // Update the value for defensive towers. Massive influence, cannot lose influence except to other defensive towers
                        _board.Tiles[i].color[_board.Tiles[i].buildingOwner] += 1;
                        for (int j = 0; j < 6; j++)
                        {
                            if (_board.Tiles[i].Neighbors[j] != null && _board.Tiles[i].Neighbors[j].TileBase != HexTileBase.Water && _board.Tiles[i].Neighbors[j].TileBase != HexTileBase.Sand)
                            {
                                _board.Tiles[i].Neighbors[j].color[_board.Tiles[i].buildingOwner]++;
                            }
                        }
                    }
                }
            }

            // Now iterate through and check if we can use scaffold values (which only come into play if the tile is unowned)
            // and total up the items to determine the owner
            for (int i = 0; i < _board.Tiles.Length; i++)
            {
                _board.Tiles[i].previousOwner = _board.Tiles[i].tileOwner;

                // finalize the color and influence
                if (_board.Tiles[i].color[PlayerColor.Red] > (_board.Tiles[i].color[PlayerColor.Blue] + _board.Tiles[i].color[PlayerColor.Green] + _board.Tiles[i].color[PlayerColor.Yellow]))
                {
                    _board.Tiles[i].tileOwner = PlayerColor.Red;
                    _board.Tiles[i].value = Math.Min(_board.Tiles[i].color[PlayerColor.Red] - (_board.Tiles[i].color[PlayerColor.Blue] + _board.Tiles[i].color[PlayerColor.Green] + _board.Tiles[i].color[PlayerColor.Yellow]), 3);
                }
                else if (_board.Tiles[i].color[PlayerColor.Blue] > (_board.Tiles[i].color[PlayerColor.Red] + _board.Tiles[i].color[PlayerColor.Green] + _board.Tiles[i].color[PlayerColor.Yellow]))
                {
                    _board.Tiles[i].tileOwner = PlayerColor.Blue;
                    _board.Tiles[i].value = Math.Min(_board.Tiles[i].color[PlayerColor.Blue] - (_board.Tiles[i].color[PlayerColor.Red] + _board.Tiles[i].color[PlayerColor.Green] + _board.Tiles[i].color[PlayerColor.Yellow]), 3);
                }
                else if (_board.Tiles[i].color[PlayerColor.Green] > (_board.Tiles[i].color[PlayerColor.Blue] + _board.Tiles[i].color[PlayerColor.Red] + _board.Tiles[i].color[PlayerColor.Yellow]))
                {
                    _board.Tiles[i].tileOwner = PlayerColor.Green;
                    _board.Tiles[i].value = Math.Min(_board.Tiles[i].color[PlayerColor.Green] - (_board.Tiles[i].color[PlayerColor.Blue] + _board.Tiles[i].color[PlayerColor.Red] + _board.Tiles[i].color[PlayerColor.Yellow]), 3);
                }
                else if (_board.Tiles[i].color[PlayerColor.Yellow] > (_board.Tiles[i].color[PlayerColor.Blue] + _board.Tiles[i].color[PlayerColor.Green] + _board.Tiles[i].color[PlayerColor.Red]))
                {
                    _board.Tiles[i].tileOwner = PlayerColor.Yellow;
                    _board.Tiles[i].value = Math.Min(_board.Tiles[i].color[PlayerColor.Yellow] - (_board.Tiles[i].color[PlayerColor.Blue] + _board.Tiles[i].color[PlayerColor.Green] + _board.Tiles[i].color[PlayerColor.Red]), 3);
                }
                else if (_board.Tiles[i].previousOwner != PlayerColor.None)
                {
                    _board.Tiles[i].tileOwner = PlayerColor.None;
                    _board.Tiles[i].value = 0;
                }

                // Reset the values for next change
                _board.Tiles[i].color[PlayerColor.Red] = 0;
                _board.Tiles[i].color[PlayerColor.Blue] = 0;
                _board.Tiles[i].color[PlayerColor.Green] = 0;
                _board.Tiles[i].color[PlayerColor.Yellow] = 0;

                // A building can never lose all it's influence, therefore check building owner and override if "covered" by opposing influence
                if (_board.Tiles[i].ManMadeModifier != HexTileManMadeModifier.None && _board.Tiles[i].buildingOwner != _board.Tiles[i].tileOwner)
                {
                    _board.Tiles[i].tileOwner = _board.Tiles[i].buildingOwner;
                    _board.Tiles[i].value = 1;
                }

                if (_board.Tiles[i].tileOwner != PlayerColor.None)
                {
                    foreach (KeyValuePair<PlayerColor, Player> p in _board.Players)
                    {
                        if (p.Value.Side == _board.Tiles[i].tileOwner)
                        {
                            // Update owned tiles (used in AI and end turn)
                            p.Value.tilesOwned.Add(i);

                            // Update possessed resources (used in AI and end turn)
                            if (_board.Tiles[i].ResourceModifier != HexTileResource.None)
                            {
                                p.Value.OwnedResources[_board.Tiles[i].ResourceModifier] += _board.Tiles[i].value;
                                p.Value.OwnedResources[HexTileResource.None]++; // Total resources count stored in "none" (used in AI)
                            }
                        }
                    }
                }

                InstancedDictionaries.UpdateQuadtreeCounts = true;
                // JAMES: Commented out and moved to a non-threaded call in the system. 
                //      The is because the removing of quadtree objects in a threaded environment can
                //      cause draw issues and the program to crash when resizing arrays in quadtree.draw. 
                //      Therefore, that must be done in another
                //      setting the the above variable triggers it to occur once
                //// Elevate the _board.Tiles and add to dictionaries to draw
                //if (_board.Tiles[i].value != _board.Tiles[i].previousValue || _board.Tiles[i].previousOwner != _board.Tiles[i].tileOwner)
                //{
                //    // Change the position
                //    if (_board.Tiles[i].value > 0)
                //    {
                //        // Remove from draw dictionaries
                //        if (_board.Tiles[i].previousOwner != PlayerColor.None || _board.Tiles[i].tileOwner != _board.Tiles[i].previousOwner)
                //        {
                //            _board.quadtree.RemoveColor(_board.Tiles[i], _board.Tiles[i].previousOwner);
                //        }

                //        // Add to be have position incrementally updated
                //        _board.Tiles[i].DesiredPosition = new Vector3(_board.Tiles[i].Position.X, BoardVariables.tileIncrement * _board.Tiles[i].value, _board.Tiles[i].Position.Z);
                //        _board.tilesToUpdate.Add(_board.Tiles[i]);

                //        // Add to draw dictionary
                //        _board.quadtree.AddColorTile(_board.Tiles[i]);
                //    }
                //    else
                //    {
                //        // Remove from draw dictionaries
                //        _board.quadtree.RemoveColor(_board.Tiles[i], _board.Tiles[i].previousOwner);

                //        // Add to be have position incrementally updated
                //        _board.Tiles[i].DesiredPosition = new Vector3(_board.Tiles[i].Position.X, 0, _board.Tiles[i].Position.Z);
                //        _board.tilesToUpdate.Add(_board.Tiles[i]);
                //    }
                //}
            }

            BoardVariables.UpdatingInfluence = false;
        }

        // Cannot multithread, as "removing" can cause draw issues with changing array size, so updateinfluence moved and called separately
        public static bool UpgradeTower(ref Board _board, int _indexInBoard, PlayerColor _side, NetworkSession networkSession)
        {
            bool canBuild = false;

            // IF the player has all towers destroyed, allow them to build anywhere
            if (!_board.currentPlayer.canBuildFirst && _board.currentPlayer.tilesOwned.Count == 0)
                canBuild = true;

            // Make a defensive tile
            if (_board.Tiles[_indexInBoard].NaturalModifier == HexTileNaturalModifier.Hill2 || _board.Tiles[_indexInBoard].NaturalModifier == HexTileNaturalModifier.Hill2 || _board.Tiles[_indexInBoard].NaturalModifier == HexTileNaturalModifier.Hill2)
            {
                if (_board.Tiles[_indexInBoard].tileOwner == _side || _board.currentPlayer.canBuildFirst)
                {
                    canBuild = true;
                    _board.currentPlayer.canBuildFirst = false;
                }
                else
                {
                    // Check two levels out to make sure we can build within this range (must be adjacent to other influence)
                    for (int j = 0; j < 6; j++)
                    {
                        if (_board.Tiles[_indexInBoard].Neighbors[j] != null && (_board.Tiles[_indexInBoard].Neighbors[j].TileBase != HexTileBase.Water || (_board.Tiles[_indexInBoard].Neighbors[j].TileBase == HexTileBase.Water && _board.Tiles[_indexInBoard].Neighbors[j].ManMadeModifier == HexTileManMadeModifier.Bridge)))
                        {
                            if (_board.Tiles[_indexInBoard].Neighbors[j].tileOwner == _side)
                            {
                                canBuild = true;
                                break;
                            }

                            for (int k = 0; k < 6; k++)
                            {
                                if (_board.Tiles[_indexInBoard].Neighbors[j].Neighbors[k] != null && _board.Tiles[_indexInBoard].Neighbors[j].Neighbors[k].tileOwner == _side)
                                {
                                    canBuild = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                if (canBuild)
                {
                    //_board.quadtree.RemoveNaturalModifier(_board.Tiles[_indexInBoard]);
                    _board.currentPlayer.canBuildFirst = false;
                    InstancedDictionaries.UpdateQuadtreeCounts = true;
                    _board.Tiles[_indexInBoard].PreviousNaturalModifier = _board.Tiles[_indexInBoard].NaturalModifier;

                    _board.Tiles[_indexInBoard].NaturalModifier = HexTileNaturalModifier.None;
                    _board.Tiles[_indexInBoard].ResourceModifier = HexTileResource.None;

                    _board.Tiles[_indexInBoard].ManMadeModifier = HexTileManMadeModifier.DefensiveTower;
                    _board.Tiles[_indexInBoard].buildingOwner = _side;
                    //_board.quadtree.AddManmadeModifier(_board.Tiles[_indexInBoard]);

                    _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.DefensiveWoodCost, new Vector2(_board.widthFraction * 5 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.DefensiveStoneCost, new Vector2(_board.widthFraction + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.DefensiveClayCost, new Vector2(_board.widthFraction * 3 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));

                    _board.currentPlayer.CurrentResources[HexTileResource.Clay] -= BoardVariables.DefensiveClayCost;
                    _board.currentPlayer.CurrentResources[HexTileResource.Stone] -= BoardVariables.DefensiveStoneCost;
                    _board.currentPlayer.CurrentResources[HexTileResource.Wood] -= BoardVariables.DefensiveWoodCost;
                }
            }
            else if (_board.Tiles[_indexInBoard].TileBase == HexTileBase.Grass && (_board.Tiles[_indexInBoard].NaturalModifier == HexTileNaturalModifier.None || _board.Tiles[_indexInBoard].NaturalModifier == HexTileNaturalModifier.Trees1 || _board.Tiles[_indexInBoard].NaturalModifier == HexTileNaturalModifier.Trees1)
                && _board.Tiles[_indexInBoard].ManMadeModifier == HexTileManMadeModifier.None)
            {
                if (_board.Tiles[_indexInBoard].tileOwner == _side || _board.currentPlayer.canBuildFirst)
                {
                    canBuild = true;
                    _board.currentPlayer.canBuildFirst = false;
                }
                else
                {
                    // Check two levels out to make sure we can build within this range (must be adjacent to other influence)
                    for (int j = 0; j < 6; j++)
                    {
                        if (_board.Tiles[_indexInBoard].Neighbors[j] != null && (_board.Tiles[_indexInBoard].Neighbors[j].TileBase != HexTileBase.Water || (_board.Tiles[_indexInBoard].Neighbors[j].TileBase == HexTileBase.Water && _board.Tiles[_indexInBoard].Neighbors[j].ManMadeModifier == HexTileManMadeModifier.Bridge)))
                        {
                            if (_board.Tiles[_indexInBoard].Neighbors[j].tileOwner == _side)
                            {
                                canBuild = true;
                                break;
                            }

                            for (int k = 0; k < 6; k++)
                            {
                                if (_board.Tiles[_indexInBoard].Neighbors[j].Neighbors[k] != null && _board.Tiles[_indexInBoard].Neighbors[j].Neighbors[k].tileOwner == _side)
                                {
                                    canBuild = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                if (canBuild)
                {
                    //_board.quadtree.RemoveNaturalModifier(_board.Tiles[_indexInBoard]);
                    _board.currentPlayer.canBuildFirst = false;
                    InstancedDictionaries.UpdateQuadtreeCounts = true;
                    _board.Tiles[_indexInBoard].PreviousNaturalModifier = _board.Tiles[_indexInBoard].NaturalModifier;

                    _board.Tiles[_indexInBoard].NaturalModifier = HexTileNaturalModifier.None;
                    _board.Tiles[_indexInBoard].ResourceModifier = HexTileResource.None;

                    _board.Tiles[_indexInBoard].ManMadeModifier = HexTileManMadeModifier.InfluenceTower1;
                    _board.Tiles[_indexInBoard].buildingOwner = _side;
                    //_board.quadtree.AddManmadeModifier(_board.Tiles[_indexInBoard]);

                    _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence1WoodCost, new Vector2(_board.widthFraction * 5 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence1StoneCost, new Vector2(_board.widthFraction + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence1ClayCost, new Vector2(_board.widthFraction * 3 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                    _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence1WheatCost, new Vector2(_board.widthFraction * 4 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));

                    _board.currentPlayer.CurrentResources[HexTileResource.Clay] -= BoardVariables.Influence1ClayCost;
                    _board.currentPlayer.CurrentResources[HexTileResource.Stone] -= BoardVariables.Influence1StoneCost;
                    _board.currentPlayer.CurrentResources[HexTileResource.Wood] -= BoardVariables.Influence1WoodCost;
                    _board.currentPlayer.CurrentResources[HexTileResource.Wheat] -= BoardVariables.Influence1WheatCost;
                }
            }
            else if (_board.Tiles[_indexInBoard].TileBase == HexTileBase.Grass && _board.Tiles[_indexInBoard].NaturalModifier == HexTileNaturalModifier.None && _board.Tiles[_indexInBoard].ManMadeModifier == HexTileManMadeModifier.InfluenceTower1)
            {
                //_board.quadtree.RemoveManMadeModifier(_board.Tiles[_indexInBoard]);
                _board.currentPlayer.canBuildFirst = false;
                InstancedDictionaries.UpdateQuadtreeCounts = true;
                _board.Tiles[_indexInBoard].PreviousManMadeModifier = _board.Tiles[_indexInBoard].ManMadeModifier;

                _board.Tiles[_indexInBoard].ManMadeModifier = HexTileManMadeModifier.InfluenceTower2;
                _board.Tiles[_indexInBoard].buildingOwner = _side;
                //_board.quadtree.AddManmadeModifier(_board.Tiles[_indexInBoard]);

                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence2WoodCost, new Vector2(_board.widthFraction * 5 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence2StoneCost, new Vector2(_board.widthFraction + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence2ClayCost, new Vector2(_board.widthFraction * 3 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence2WheatCost, new Vector2(_board.widthFraction * 4 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));

                _board.currentPlayer.CurrentResources[HexTileResource.Clay] -= BoardVariables.Influence2ClayCost;
                _board.currentPlayer.CurrentResources[HexTileResource.Stone] -= BoardVariables.Influence2StoneCost;
                _board.currentPlayer.CurrentResources[HexTileResource.Wood] -= BoardVariables.Influence2WoodCost;
                _board.currentPlayer.CurrentResources[HexTileResource.Wheat] -= BoardVariables.Influence2WheatCost;

                canBuild = true;
            }
            else if (_board.Tiles[_indexInBoard].TileBase == HexTileBase.Grass && _board.Tiles[_indexInBoard].NaturalModifier == HexTileNaturalModifier.None && _board.Tiles[_indexInBoard].ManMadeModifier == HexTileManMadeModifier.InfluenceTower2)
            {
                //_board.quadtree.RemoveManMadeModifier(_board.Tiles[_indexInBoard]);
                _board.currentPlayer.canBuildFirst = false;
                InstancedDictionaries.UpdateQuadtreeCounts = true;
                _board.Tiles[_indexInBoard].PreviousManMadeModifier = _board.Tiles[_indexInBoard].ManMadeModifier;

                _board.Tiles[_indexInBoard].ManMadeModifier = HexTileManMadeModifier.InfluenceTower3;
                _board.Tiles[_indexInBoard].buildingOwner = _side;
                //_board.quadtree.AddManmadeModifier(_board.Tiles[_indexInBoard]);

                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence3WoodCost, new Vector2(_board.widthFraction * 5 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence3StoneCost, new Vector2(_board.widthFraction + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence3ClayCost, new Vector2(_board.widthFraction * 3 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.Influence3WheatCost, new Vector2(_board.widthFraction * 4 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));

                _board.currentPlayer.CurrentResources[HexTileResource.Clay] -= BoardVariables.Influence3ClayCost;
                _board.currentPlayer.CurrentResources[HexTileResource.Stone] -= BoardVariables.Influence3StoneCost;
                _board.currentPlayer.CurrentResources[HexTileResource.Wood] -= BoardVariables.Influence3WoodCost;
                _board.currentPlayer.CurrentResources[HexTileResource.Wheat] -= BoardVariables.Influence3WheatCost;

                canBuild = true;
            }
            else if (_board.Tiles[_indexInBoard].TileBase == HexTileBase.Water)
            {
                InstancedDictionaries.UpdateQuadtreeCounts = true;
                _board.Tiles[_indexInBoard].PreviousManMadeModifier = _board.Tiles[_indexInBoard].ManMadeModifier;
                _board.Tiles[_indexInBoard].ManMadeModifier = HexTileManMadeModifier.Bridge;
                //_board.quadtree.AddManmadeModifier(_board.Tiles[_indexInBoard]);

                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.BridgeWoodCost, new Vector2(_board.widthFraction * 5 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.BridgeClayCost, new Vector2(_board.widthFraction + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("-" + BoardVariables.BridgeStoneCost, new Vector2(_board.widthFraction * 3 + 100, _board.heightPadding * 9 - 64), _board.spriteFont, Color.White, 0, 1000, -Vector2.UnitY, 0.1f, 1.0f, -0.003f, 500, 0.0f, 1000, DynamicTextLine.OriginType.TopLeft, _board.currentPlayer.color));

                _board.currentPlayer.CurrentResources[HexTileResource.Clay] -= BoardVariables.BridgeClayCost;
                _board.currentPlayer.CurrentResources[HexTileResource.Stone] -= BoardVariables.BridgeStoneCost;
                _board.currentPlayer.CurrentResources[HexTileResource.Wood] -= BoardVariables.BridgeWoodCost;

                canBuild = true;
            }

            // Add settling particle
            if (canBuild)
            {
                // Play sounds
                if (_board.Tiles[_indexInBoard].ManMadeModifier == HexTileManMadeModifier.Bridge)
                {
                    _board.waterSound.Play();
                }
                else
                {
                    _board.constructSound.Play();
                }

                for (int i = 0; i < 30; i++)
                {
                    _board.settlingParticles.AddParticle(new Vector3(_board.Tiles[_indexInBoard].Position.X, _board.Tiles[_indexInBoard].Position.Y + (BoardVariables.tileIncrement), _board.Tiles[_indexInBoard].Position.Z), new Vector3(0, 20, 0));
                }

                // Send network updates
                if ((networkSession != null) && (networkSession.LocalGamers.Count > 0))
                {
                    PacketWriter packetWriter = new PacketWriter();

                    // write the identification value
                    packetWriter.Write((Int32)PacketTypes.PlayerAction);

                    // Send the active
                    packetWriter.Write((Int32)_board.currentPlayer.Side);

                    // Send our "End Turn" action
                    packetWriter.Write((Int32)PlayerActions.UpgradeTower);

                    // Send empty values for source/target indices
                    packetWriter.Write((Int32)(_indexInBoard));
                    packetWriter.Write((Int32)(-1));

                    networkSession.LocalGamers[0].SendData(packetWriter, SendDataOptions.ReliableInOrder);
                }
            }
            else
            {
                _board.errorSound.Play(0.2f, 0.0f, 0.0f);
                _board.dynamicText.DynamicTextLines.Add(new DynamicTextLine("Cannot build where influence will not be continuous.", new Vector2((_board.screenWidth / 2) - (_board.spriteFontSmall.MeasureString("Cannot build where influence will not be continuous.").X / 2), _board.heightPadding * 6), _board.spriteFontSmall, Color.White, 0, 2000, -Vector2.UnitY, 0.05f, 1.0f, -0.0015f, 1000, 0.0f, 2000, DynamicTextLine.OriginType.TopLeft, Color.Black));
            }

            // Update Influence
            //UpdateInfluence(ref _board);

            return canBuild;
        }

        // Cannot multithread, as "removing" can cause draw issues with changing array size, so updateinfluence moved and called separately
        public static void ReduceTower(ref Board _board, int _sourceTargetInBoard, int _targetIndexInBoard, NetworkSession networkSession)
        {
            if (_board.Tiles[_targetIndexInBoard].ManMadeModifier == HexTileManMadeModifier.None)
                return;

            // Send network updates
            if ((networkSession != null) && (networkSession.LocalGamers.Count > 0))
            {
                PacketWriter packetWriter = new PacketWriter();

                // write the identification value
                packetWriter.Write((Int32)PacketTypes.PlayerAction);

                // Send the active
                packetWriter.Write((Int32)_board.currentPlayer.Side);

                // Send our "End Turn" action
                packetWriter.Write((Int32)PlayerActions.ReduceTower);

                // Send empty values for source/target indices
                packetWriter.Write((Int32)(_sourceTargetInBoard));
                packetWriter.Write((Int32)(_targetIndexInBoard));

                networkSession.LocalGamers[0].SendData(packetWriter, SendDataOptions.ReliableInOrder);
            }

            // Play sound
            _board.cannonSound.Play();

            // Tag for update
            InstancedDictionaries.UpdateQuadtreeCounts = true;
            _board.Tiles[_targetIndexInBoard].PreviousManMadeModifier = _board.Tiles[_targetIndexInBoard].ManMadeModifier;

            // Add cannon particle
            Vector3 cannonDirection = Vector3.Normalize(_board.Tiles[_targetIndexInBoard].Position - _board.Tiles[_sourceTargetInBoard].Position);
            cannonDirection.Y = 0.5f;
            for (int i = 0; i < 80; i++)
            {
                _board.cannonParticles.AddParticle(_board.Tiles[_sourceTargetInBoard].Position, cannonDirection * BoardConstructor.random.Next(120, 400));
            }
            // Add settling particle
            for (int i = 0; i < 50; i++)
            {
                _board.settlingParticles.AddParticle(_board.Tiles[_targetIndexInBoard].Position, Vector3.Zero);
            }

            // Reduce the opponents tower
            if (_board.Tiles[_targetIndexInBoard].ManMadeModifier == HexTileManMadeModifier.InfluenceTower3)
            {
                _board.Tiles[_targetIndexInBoard].ManMadeModifier = HexTileManMadeModifier.InfluenceTower2;

                //_board.quadtree.AddManmadeModifier(_board.Tiles[_indexInBoard]);
            }
            else if (_board.Tiles[_targetIndexInBoard].ManMadeModifier == HexTileManMadeModifier.InfluenceTower2)
            {
                _board.Tiles[_targetIndexInBoard].ManMadeModifier = HexTileManMadeModifier.InfluenceTower1;

                //_board.quadtree.AddManmadeModifier(_board.Tiles[_indexInBoard]);
            }
            else if (_board.Tiles[_targetIndexInBoard].ManMadeModifier == HexTileManMadeModifier.InfluenceTower1)
            {
                // force remove last color
                //_board.Tiles[_indexInBoard].previousOwner = PlayerColor.None;
                _board.Tiles[_targetIndexInBoard].ManMadeModifier = HexTileManMadeModifier.None;
            }
            else if (_board.Tiles[_targetIndexInBoard].ManMadeModifier == HexTileManMadeModifier.DefensiveTower)
            {
                return;
            }
            else if (_board.Tiles[_targetIndexInBoard].ManMadeModifier == HexTileManMadeModifier.Bridge)
            {
                _board.Tiles[_targetIndexInBoard].ManMadeModifier = HexTileManMadeModifier.None;
            }

            // Update Influence
            //UpdateInfluence(ref _board);
            //#if XBOX
            //            Thread.CurrentThread.SetProcessorAffinity(5);
            //#endif
            //            System.Threading.ThreadPool.QueueUserWorkItem(Func =>
            //            {
            //                //T result = ReadObject<T>(filename);
            //                //callback(result);
            //                UpdateInfluenceThreaded();
            //            });
        }
    }
}
